package com.googlecode.utterlyidle.multipart;

import com.googlecode.totallylazy.Pair;
import com.googlecode.totallylazy.Predicate;
import com.googlecode.utterlyidle.Entity;
import com.googlecode.utterlyidle.HttpHeaders;
import com.googlecode.utterlyidle.MediaType;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import static com.googlecode.totallylazy.Pair.pair;
import static com.googlecode.totallylazy.Sequences.sequence;
import static com.googlecode.utterlyidle.HeaderParameters.headerParameters;

public class PartBuilder {
    private final byte[] body;
    private final List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();

    public PartBuilder(byte[] body) {
        this.body = body;
    }

    public PartBuilder(String body) throws UnsupportedEncodingException {
        this.body = body.getBytes(Entity.DEFAULT_CHARACTER_SET);
    }

    public static PartBuilder body(byte[] body) {
        return new PartBuilder(body);
    }

    public static PartBuilder body(String body) {
        try {
            return new PartBuilder(body);
        } catch(UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public PartBuilder header(String name, Object value) {
        if (value == null) {
            return this;
        }

        headers.add(pair(name, value.toString()));
        return this;
    }

    public PartBuilder contentType(String contentType) {
        return header(HttpHeaders.CONTENT_TYPE, contentType);
    }

    public PartBuilder contentDisposition(String contentDisposition) {
        return header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition);
    }

    public PartBuilder contentDisposition(ContentDisposition contentDisposition) {
        return header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString());
    }

    public Part build() {
        if(!sequence(headers).exists(contentType())) {
            contentType(MediaType.TEXT_PLAIN);
        }
        return Part.part(headerParameters(headers), Entity.entity(body));
    }

    private Predicate<Pair<String, String>> contentType() {
        return new Predicate<Pair<String, String>>() {
            @Override
            public boolean matches(Pair<String, String> pair) {
                return pair.first().equals(HttpHeaders.CONTENT_TYPE);
            }
        };
    }
}
